package org.java.auth.handler;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.java.commons.vo.Result;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.access.AccessDeniedHandlerImpl;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class SmartHandler extends SavedRequestAwareAuthenticationSuccessHandler implements AuthenticationFailureHandler, AccessDeniedHandler {

    //    负责转换JSON和java对象
    private ObjectMapper objectMapper = new ObjectMapper();
//    默认的访问拒绝处理器
    private AccessDeniedHandlerImpl defaultDeniedHandler = new AccessDeniedHandlerImpl();

    public SmartHandler(){

    }

    public SmartHandler(String errorPage){
        defaultDeniedHandler.setErrorPage(errorPage);
    }

    public boolean sendJson(Result result,
                                 HttpServletRequest httpServletRequest,
                                 HttpServletResponse httpServletResponse
    ) throws IOException {
        String accept = httpServletRequest.getHeader("Accept");
        if (accept != null && accept.startsWith("application/json")) {
            // 把对象转换为JSON
            String json = objectMapper.writeValueAsString(result);
            httpServletResponse.setContentType("application/json; charset=UTF-8");
            httpServletResponse.getWriter().println(json);
            return true;
        } else {
            return false;
        }

    }

    @Override
    public void onAuthenticationFailure(HttpServletRequest httpServletRequest,
                                        HttpServletResponse httpServletResponse,
                                        AuthenticationException e
    ) throws IOException, ServletException {
            Result result = Result.error("登录失败" + e.getLocalizedMessage());
            if (!this.sendJson(result,httpServletRequest,httpServletResponse)){
//              返回HTML的时候，重定向到登录页面
                httpServletResponse.sendRedirect("./login");
        }
    }

    @Override
    public void onAuthenticationSuccess(HttpServletRequest httpServletRequest,
                                        HttpServletResponse httpServletResponse,
                                        Authentication authentication
    ) throws ServletException, IOException {
            Result result = Result.error("登录成功" );
            if (!this.sendJson(result,httpServletRequest,httpServletResponse)){
//                没发json，就执行保存
                super.onAuthenticationSuccess(httpServletRequest,httpServletResponse,authentication);
    }
    }


    @Override
    public void handle(HttpServletRequest request,
                       HttpServletResponse response,
                       AccessDeniedException e
    ) throws IOException, ServletException {
        Result result = Result.error("访问被拒绝："+e.getLocalizedMessage());
        response.setStatus(403);
        if (!this.sendJson(result,request,response)){
//          没发送json,使用默认访问拒绝处理器
            defaultDeniedHandler.handle(request,response, e);
        }
    }
}